using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace StoryDesigner.Controls
{
	public class StoryControlBase : Control
	{
		public new event EventHandler GotFocus;
		private Border _dragTop;
		private Border _dragLeftMiddle;
		private Border _dragRightMiddle;
		private Border _dragLeftBottom;
		private Border _dragMiddleBottom;
		private Border _dragRightBottom;
		private Point _normalPosition;
		public override void OnApplyTemplate()
		{
			base.OnApplyTemplate();
			InvalidateMeasure();
			double originalWidth = ActualWidth;
			double originalHeight = ActualHeight;

			#region DragBorder initialization
			#region Top
			_dragTop = GetTemplateChild("dragTop") as Border;
			bool isDragging = false;
			Point clickPoint = new Point();
			Point windowPos = new Point();
			_dragTop.MouseLeftButtonDown += (s, e) =>
			{
				isDragging = true;
				clickPoint = e.GetPosition(null);
				_dragTop.CaptureMouse();
				windowPos = new Point(Canvas.GetLeft(this), Canvas.GetTop(this));
			};

			_dragTop.MouseLeftButtonUp += (s, e) =>
			{
				isDragging = false;
				_dragTop.ReleaseMouseCapture();
				_normalPosition = new Point(Canvas.GetLeft(this), Canvas.GetTop(this));
			};

			_dragTop.MouseMove += (s, e) =>
			{
				if (!isDragging)
					return;
				Point currentMousePos = e.GetPosition(null);
				Point delta = new Point(currentMousePos.X - clickPoint.X, currentMousePos.Y - clickPoint.Y);
				Canvas.SetLeft(this, windowPos.X + delta.X);
				Canvas.SetTop(this, windowPos.Y + delta.Y);
			};
			#endregion

			#region Left Middle
			_dragLeftMiddle = GetTemplateChild("dragLeftMiddle") as Border;
			if (_dragLeftMiddle != null)
			{
				clickPoint = new Point();
				bool isResizing = false;
				_dragLeftMiddle.MouseLeftButtonDown += (s, e) =>
				{
					isResizing = true;
					clickPoint = e.GetPosition(null);
					originalHeight = ActualHeight;
					originalWidth = ActualWidth;
					_dragLeftMiddle.CaptureMouse();
				};

				_dragLeftMiddle.MouseLeftButtonUp += (s, e) =>
				{
					isResizing = false;
					_dragLeftMiddle.ReleaseMouseCapture();
					originalWidth = ActualWidth;
					_normalPosition = new Point(Canvas.GetLeft(this), Canvas.GetTop(this));
				};

				_dragLeftMiddle.MouseMove += (s, e) =>
				{
					if (!isResizing) return;
					Point currPos = e.GetPosition(null);
					double width = originalWidth + (clickPoint.X - currPos.X);
					if (width > 100)
					{
						Width = width;
						double delta = originalWidth - width;
						Canvas.SetLeft(this, _normalPosition.X + (delta));
					}
				};
			}
			#endregion

			#region Right Middle
			_dragRightMiddle = GetTemplateChild("dragRightMiddle") as Border;
			if (_dragRightMiddle != null)
			{
				clickPoint = new Point();
				bool isResizing = false;
				_dragRightMiddle.MouseLeftButtonDown += (s, e) =>
				{
					isResizing = true;
					clickPoint = e.GetPosition(null);
					originalHeight = ActualHeight;
					originalWidth = ActualWidth;
					_dragRightMiddle.CaptureMouse();
				};

				_dragRightMiddle.MouseLeftButtonUp += (s, e) =>
				{
					isResizing = false;
					_dragRightMiddle.ReleaseMouseCapture();
					originalWidth = ActualWidth;
				};

				_dragRightMiddle.MouseMove += (s, e) =>
				{
					if (!isResizing) return;
					Point currPos = e.GetPosition(null);
					double width = originalWidth + (currPos.X - clickPoint.X);
					if (width > 100)
						Width = width;
				};
			}

			#endregion

			#region Left Bottom
			_dragLeftBottom = GetTemplateChild("dragLeftBottom") as Border;
			if (_dragLeftBottom != null)
			{
				_dragLeftBottom.Cursor = Cursors.SizeNESW;
				clickPoint = new Point();
				bool isResizing = false;
				_dragLeftBottom.MouseLeftButtonDown += (s, e) =>
				{
					isResizing = true;
					clickPoint = e.GetPosition(null);
					originalHeight = ActualHeight;
					originalWidth = ActualWidth;
					_dragLeftBottom.CaptureMouse();
				};

				_dragLeftBottom.MouseLeftButtonUp += (s, e) =>
				{
					isResizing = false;
					_dragLeftBottom.ReleaseMouseCapture();
					originalHeight = ActualHeight;
					originalWidth = ActualWidth;
					_normalPosition = new Point(Canvas.GetLeft(this), Canvas.GetTop(this));
				};

				_dragLeftBottom.MouseMove += (s, e) =>
				{
					if (!isResizing) return;
					Point currPos = e.GetPosition(null);
					double width = originalWidth + (clickPoint.X - currPos.X);
					double height = originalHeight + (currPos.Y - clickPoint.Y);

					if (height > 50)
						Height = height;

					if (width > 50)
					{
						Width = width;
						double delta = originalWidth - width;
						Canvas.SetLeft(this, _normalPosition.X + (delta));
					}
				};
			}
			#endregion

			#region Middle Bottom
			_dragMiddleBottom = GetTemplateChild("dragMiddleBottom") as Border;
			if (_dragMiddleBottom != null)
			{
				clickPoint = new Point();
				bool isResizing = false;
				_dragMiddleBottom.MouseLeftButtonDown += (s, e) =>
				{
					isResizing = true;
					clickPoint = e.GetPosition(null);
					originalHeight = ActualHeight;
					originalWidth = ActualWidth;
					_dragMiddleBottom.CaptureMouse();
				};

				_dragMiddleBottom.MouseLeftButtonUp += (s, e) =>
				{
					isResizing = false;
					_dragMiddleBottom.ReleaseMouseCapture();
					originalHeight = ActualHeight;
				};

				_dragMiddleBottom.MouseMove += (s, e) =>
				{
					if (!isResizing) return;
					Point currPos = e.GetPosition(null);
					double height = originalHeight + (currPos.Y - clickPoint.Y);
					if (height > 50)
						Height = height;
				};
			}
			#endregion

			#region Right Bottom
			_dragRightBottom = GetTemplateChild("dragRightBottom") as Border;
			if (_dragRightBottom != null)
			{
				_dragRightBottom.Cursor = Cursors.SizeNWSE;
				clickPoint = new Point();
				bool isResizing = false;
				_dragRightBottom.MouseLeftButtonDown += (s, e) =>
				{
					isResizing = true;
					clickPoint = e.GetPosition(null);
					originalHeight = ActualHeight;
					originalWidth = ActualWidth;
					_dragRightBottom.CaptureMouse();
				};

				_dragRightBottom.MouseLeftButtonUp += (s, e) =>
				{
					isResizing = false;
					_dragRightBottom.ReleaseMouseCapture();
					originalHeight = ActualHeight;
					originalWidth = ActualWidth;
				};

				_dragRightBottom.MouseMove += (s, e) =>
				{
					if (!isResizing) return;
					Point currPos = e.GetPosition(null);
					double width = originalWidth + (currPos.X - clickPoint.X);
					double height = originalHeight + (currPos.Y - clickPoint.Y);
					if (height > 50)
						Height = height;
					if (width > 50)
						Width = width;
				};
			}
			#endregion
			#endregion
		}

		protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
		{
			e.Handled = true;

			if (GotFocus != null)
				GotFocus(this, null);
			base.OnMouseLeftButtonDown(e);
		}
	}

	#region Old
	//public class StoryArcControlOld : Control
	//{
	//    public event EventHandler GotFocus;
	//    public event EventHandler<OpenListEventArgs> CreateNewSubObject;
	//    public event EventHandler Changed;
	//    private TextBlock _txtBoxName;
	//    private Border _dragTop;
	//    private Border _dragLeftMiddle;
	//    private Border _dragRightMiddle;
	//    private Border _dragLeftBottom;
	//    private Border _dragMiddleBottom;
	//    private Border _dragRightBottom;
	//    private Grid _grdContent;
	//    private GridSplitter _splitter;

	//    public StoryArcControlOld()
	//    {
	//        //DefaultStyleKey = typeof(StoryArcControl);
	//    }

	//    private Point _normalPosition;

	//    public override void OnApplyTemplate()
	//    {
	//        base.OnApplyTemplate();

	//        #region DragBorder initialization
	//        #region Top
	//        _dragTop = GetTemplateChild("dragTop") as Border;
	//        bool isDragging = false;
	//        Point clickPoint = new Point();
	//        Point windowPos = new Point();
	//        _dragTop.MouseLeftButtonDown += (s, e) =>
	//        {
	//            isDragging = true;
	//            clickPoint = e.GetPosition(null);
	//            _dragTop.CaptureMouse();
	//            windowPos = new Point(Canvas.GetLeft(this), Canvas.GetTop(this));
	//        };

	//        _dragTop.MouseLeftButtonUp += (s, e) =>
	//        {
	//            isDragging = false;
	//            _dragTop.ReleaseMouseCapture();
	//            _normalPosition = new Point(Canvas.GetLeft(this), Canvas.GetTop(this));
	//        };

	//        _dragTop.MouseMove += (s, e) =>
	//        {
	//            if (!isDragging)
	//                return;
	//            Point currentMousePos = e.GetPosition(null);
	//            Point delta = new Point(currentMousePos.X - clickPoint.X, currentMousePos.Y - clickPoint.Y);
	//            Canvas.SetLeft(this, windowPos.X + delta.X);
	//            Canvas.SetTop(this, windowPos.Y + delta.Y);
	//        };
	//        #endregion

	//        double originalWidth = Width;
	//        double originalHeight = Height;
	//        #region Left Middle
	//        _dragLeftMiddle = GetTemplateChild("dragLeftMiddle") as Border;
	//        if (_dragLeftMiddle != null)
	//        {
	//            clickPoint = new Point();
	//            bool isResizing = false;
	//            _dragLeftMiddle.MouseLeftButtonDown += (s, e) =>
	//            {
	//                isResizing = true;
	//                clickPoint = e.GetPosition(null);
	//                _dragLeftMiddle.CaptureMouse();
	//            };

	//            _dragLeftMiddle.MouseLeftButtonUp += (s, e) =>
	//            {
	//                isResizing = false;
	//                _dragLeftMiddle.ReleaseMouseCapture();
	//                originalWidth = Width;
	//                _normalPosition = new Point(Canvas.GetLeft(this), Canvas.GetTop(this));
	//            };

	//            _dragLeftMiddle.MouseMove += (s, e) =>
	//            {
	//                if (!isResizing) return;
	//                Point currPos = e.GetPosition(null);
	//                double width = originalWidth + (clickPoint.X - currPos.X);
	//                if (width > 100)
	//                {
	//                    Width = width;
	//                    double delta = originalWidth - width;
	//                    Canvas.SetLeft(this, _normalPosition.X + (delta));
	//                }
	//            };
	//        }
	//        #endregion

	//        #region Right Middle
	//        _dragRightMiddle = GetTemplateChild("dragRightMiddle") as Border;
	//        if (_dragRightMiddle != null)
	//        {
	//            clickPoint = new Point();
	//            bool isResizing = false;
	//            _dragRightMiddle.MouseLeftButtonDown += (s, e) =>
	//            {
	//                isResizing = true;
	//                clickPoint = e.GetPosition(null);
	//                _dragRightMiddle.CaptureMouse();
	//            };

	//            _dragRightMiddle.MouseLeftButtonUp += (s, e) =>
	//            {
	//                isResizing = false;
	//                _dragRightMiddle.ReleaseMouseCapture();
	//                originalWidth = Width;
	//            };

	//            _dragRightMiddle.MouseMove += (s, e) =>
	//            {
	//                if (!isResizing) return;
	//                Point currPos = e.GetPosition(null);
	//                double width = originalWidth + (currPos.X - clickPoint.X);
	//                if (width > 100)
	//                    Width = width;
	//            };
	//        }

	//        #endregion

	//        #region Left Bottom
	//        _dragLeftBottom = GetTemplateChild("dragLeftBottom") as Border;
	//        if (_dragLeftBottom != null)
	//        {
	//            _dragLeftBottom.Cursor = Cursors.SizeNESW;
	//            clickPoint = new Point();
	//            bool isResizing = false;
	//            _dragLeftBottom.MouseLeftButtonDown += (s, e) =>
	//            {
	//                isResizing = true;
	//                clickPoint = e.GetPosition(null);
	//                _dragLeftBottom.CaptureMouse();
	//            };

	//            _dragLeftBottom.MouseLeftButtonUp += (s, e) =>
	//            {
	//                isResizing = false;
	//                _dragLeftBottom.ReleaseMouseCapture();
	//                originalHeight = Height;
	//                originalWidth = Width;
	//                _normalPosition = new Point(Canvas.GetLeft(this), Canvas.GetTop(this));
	//            };

	//            _dragLeftBottom.MouseMove += (s, e) =>
	//            {
	//                if (!isResizing) return;
	//                Point currPos = e.GetPosition(null);
	//                double width = originalWidth + (clickPoint.X - currPos.X);
	//                double height = originalHeight + (currPos.Y - clickPoint.Y);

	//                if (height > 200)
	//                    Height = height;

	//                if (width > 100)
	//                {
	//                    Width = width;
	//                    double delta = originalWidth - width;
	//                    Canvas.SetLeft(this, _normalPosition.X + (delta));
	//                }
	//            };
	//        }
	//        #endregion

	//        #region Middle Bottom
	//        _dragMiddleBottom = GetTemplateChild("dragMiddleBottom") as Border;
	//        if (_dragMiddleBottom != null)
	//        {
	//            clickPoint = new Point();
	//            bool isResizing = false;
	//            _dragMiddleBottom.MouseLeftButtonDown += (s, e) =>
	//            {
	//                isResizing = true;
	//                clickPoint = e.GetPosition(null);
	//                _dragMiddleBottom.CaptureMouse();
	//            };

	//            _dragMiddleBottom.MouseLeftButtonUp += (s, e) =>
	//            {
	//                isResizing = false;
	//                _dragMiddleBottom.ReleaseMouseCapture();
	//                originalHeight = Height;
	//            };

	//            _dragMiddleBottom.MouseMove += (s, e) =>
	//            {
	//                if (!isResizing) return;
	//                Point currPos = e.GetPosition(null);
	//                double height = originalHeight + (currPos.Y - clickPoint.Y);
	//                if (height > 200)
	//                    Height = height;
	//            };
	//        }
	//        #endregion

	//        #region Right Bottom
	//        _dragRightBottom = GetTemplateChild("dragRightBottom") as Border;
	//        if (_dragRightBottom != null)
	//        {
	//            _dragRightBottom.Cursor = Cursors.SizeNWSE;
	//            clickPoint = new Point();
	//            bool isResizing = false;
	//            _dragRightBottom.MouseLeftButtonDown += (s, e) =>
	//            {
	//                isResizing = true;
	//                clickPoint = e.GetPosition(null);
	//                _dragRightBottom.CaptureMouse();
	//            };

	//            _dragRightBottom.MouseLeftButtonUp += (s, e) =>
	//            {
	//                isResizing = false;
	//                _dragRightBottom.ReleaseMouseCapture();
	//                originalHeight = Height;
	//                originalWidth = Width;
	//            };

	//            _dragRightBottom.MouseMove += (s, e) =>
	//            {
	//                if (!isResizing) return;
	//                Point currPos = e.GetPosition(null);
	//                double width = originalWidth + (currPos.X - clickPoint.X);
	//                double height = originalHeight + (currPos.Y - clickPoint.Y);
	//                if (height > 200)
	//                    Height = height;
	//                if (width > 100)
	//                    Width = width;
	//            };
	//        }
	//        #endregion
	//        #endregion

	//        _txtBoxName = GetTemplateChild("txtBoxName") as TextBlock;
	//        _grdContent = GetTemplateChild("grdContent") as Grid;
	//        _splitter = GetTemplateChild("splitter") as GridSplitter;
	//        _splitter.Margin = new Thickness(-2,0,0,0);
	//        InitializeContents();
	//    }

	//    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
	//    {
	//        e.Handled = true;
	//        if (GotFocus != null)
	//            GotFocus(this, null);
	//        base.OnMouseLeftButtonDown(e);
	//    }

	//    /// <summary>
	//    /// This is all nice and well, but it would be better if the B key was on the right, instead of a double width N key for no damn reason at all.
	//    /// However, this control should be redesigned from being generic to being type specific, just like in the normal game client.
	//    /// Making this generic is wayyy too much finger- and head breaking compared to doing it concretely.
	//    /// </summary>
	//    private void InitializeContents()
	//    {
	//        if (DataContext == null)
	//            return;

	//        string boxname = DataContext.GetType().UnderlyingSystemType.Name;
	//        Regex r = new Regex(@"\S*(?<Last>[A-Z][a-z0-9]+)");
	//        Regex r2 = new Regex(@"\A(?<command>\S*)(\s+(?<parameter>[\S|\s]*))?\Z");
	//        var match = r.Match(boxname);
	//        boxname = match.Groups["Last"].Value;
	//        if (_txtBoxName != null)
	//            _txtBoxName.Text = boxname;

	//        Type t = DataContext.GetType().UnderlyingSystemType;
	//        PropertyInfo[] pInfos = t.GetProperties();
	//        int currentRow = 0;
	//        foreach(PropertyInfo pi in pInfos)
	//        {
	//            _grdContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(0, GridUnitType.Auto) });
	//            TextBlock name = new TextBlock { Text = pi.Name, TextWrapping = TextWrapping.NoWrap };
	//            name.SetValue(Grid.RowProperty, currentRow);
	//            name.SetValue(Grid.ColumnProperty, 0);
	//            if (pi.PropertyType.IsGenericType)
	//            {
	//                //add "..." button
	//                Button listButton = new Button {Content = "...", HorizontalAlignment = HorizontalAlignment.Right};
	//                listButton.SetValue(Grid.RowProperty, currentRow);
	//                listButton.SetValue(Grid.ColumnProperty, 1);
	//                listButton.Tag = pi.PropertyType.GetProperties()[2].PropertyType;
	//                _grdContent.Children.Add(listButton);

	//                Popup pop = new Popup {HorizontalAlignment = HorizontalAlignment.Stretch};
	//                pop.SetValue(Grid.RowProperty, currentRow);
	//                pop.SetValue(Grid.ColumnProperty, 1);
	//                _grdContent.Children.Add(pop);
	//                ListBox popEntries = new ListBox { Height = 100, HorizontalAlignment = HorizontalAlignment.Stretch, DisplayMemberPath = "Title"};
	//                popEntries.SelectionChanged += PopEntriesSelectionChanged;
	//                popEntries.SetBinding(ListBox.ItemsSourceProperty, new Binding(pi.Name){Mode = BindingMode.TwoWay});
	//                pop.Child = popEntries;
	//                listButton.Click += (s, e) => { pop.IsOpen = !pop.IsOpen; };
	//            }
	//            else if(pi.PropertyType.IsEnum)
	//            {
	//                //bind enum values to ItemsSource
	//                var fields = pi.PropertyType.GetFields().Where(it => it.IsLiteral).ToList();
	//                List<string> values = fields.Select(field => field.Name).ToList();

	//                ComboBox cbx = new ComboBox {ItemsSource = values, HorizontalAlignment = HorizontalAlignment.Stretch};
	//                cbx.SetBinding(ComboBox.SelectedItemProperty, new Binding(pi.Name) { Mode = BindingMode.TwoWay, Converter = new EnumValueConverter() });
	//                cbx.SetValue(Grid.RowProperty, currentRow);
	//                cbx.SetValue(Grid.ColumnProperty, 1);
	//                cbx.SelectionChanged += (s, e) =>
	//                {
	//                    if (Changed != null)
	//                        Changed(this, null);
	//                };
	//                _grdContent.Children.Add(cbx);
	//            }
	//            else
	//            {
	//                TextBox value = new TextBox();
	//                value.SetBinding(TextBox.TextProperty, new Binding(pi.Name){Mode = BindingMode.TwoWay});
	//                value.SetValue(Grid.RowProperty, currentRow);
	//                value.SetValue(Grid.ColumnProperty, 1);
	//                if (pi.PropertyType == typeof (ulong) || pi.PropertyType == typeof (DateTime))
	//                    value.IsReadOnly = true;
	//                value.TextChanged += (s, e) =>
	//                {
	//                    if (Changed != null)
	//                        Changed(this, null);
	//                };
	//                _grdContent.Children.Add(value);
	//            }
	//            _grdContent.Children.Add(name);

	//            currentRow++;
	//        }
	//        _grdContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
	//        _grdContent.Children.Remove(_splitter);
	//        _grdContent.Children.Add(_splitter);
	//    }

	//    void PopEntriesSelectionChanged(object sender, SelectionChangedEventArgs e)
	//    {
	//        //create new object fitting into the ItemsSource of sender
	//        Type thisListBoxItemType = ((ListBox) sender).ItemsSource.GetType().GetGenericArguments()[0];
	//        var newObject = Activator.CreateInstance(thisListBoxItemType);
	//        string propertyName = ((ListBox) sender).GetBindingExpression(ListBox.ItemsSourceProperty).ParentBinding.Path.Path;
	//        //signal the creation of this object to the outside, so that a new itemcontrol can be created and displayed)
	//        if (CreateNewSubObject != null)
	//            CreateNewSubObject(this, new OpenListEventArgs {NewObject = newObject, PropertyName = propertyName});
	//        //add the new object to the itemssource
	//    }
	//}
	#endregion
}